home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / pascal / xlibpas.zip / XLIB.DOC < prev    next >
Text File  |  1993-10-24  |  58KB  |  1,512 lines

  1. ╔═══════════════════════════════════════════════════════════════════════════╗
  2. ║                                                                           ║
  3. ║       XLIB - Graphics Library for Borland/Turbo Pascal v6.0/7.0           ║
  4. ║                                                                           ║
  5. ╠═══════════════════════════════════════════════════════════════════════════╣
  6. ║                                                                           ║
  7. ║                             Original code by                              ║
  8. ║                                                                           ║
  9. ║                  Themie Gouthas - egg@dstos3.dsto.gov.au                  ║
  10. ║                                                                           ║
  11. ║         Some of the code in this library has been contributed by :        ║
  12. ║                                                                           ║
  13. ║                    Matthew MacKenzie - matm@eng.umd.edu                   ║
  14. ║                                                                           ║
  15. ║           I informally reserve all rights to the code in XLIB             ║
  16. ║       Rights to contributed code is also assumed to be reserved by        ║
  17. ║                          the original authors.                            ║
  18. ║                                                                           ║
  19. ╠═══════════════════════════════════════════════════════════════════════════╣
  20. ║                                                                           ║
  21. ║             Conversion to Borland/Turbo Pascal v6.0/7.0 by                ║
  22. ║                                                                           ║
  23. ║               Tristan Tarrant - tristant@cogs.susx.ac.uk                  ║
  24. ║                                                                           ║
  25. ╚═══════════════════════════════════════════════════════════════════════════╝
  26.  
  27. ╔═══════════════════════════════════════════════════════════════════════════╗
  28. ║ DISCLAIMER                                                                ║
  29. ╚═══════════════════════════════════════════════════════════════════════════╝
  30.  
  31.     This library is distributed AS IS. The author/s specifically disclaim any
  32.     responsibility for any loss of profit or any incidental, consequential or
  33.     other damages.
  34.  
  35. ╔═══════════════════════════════════════════════════════════════════════════╗
  36. ║ INTRODUCTION                                                              ║
  37. ╚═══════════════════════════════════════════════════════════════════════════╝
  38.  
  39.     XLIB is a "user supported freeware" graphics library specifically designed
  40.     with game programming in mind.
  41.  
  42.     It has been placed in the public domain for the benefit of all, and
  43.     represents *MANY* hours of work so it is requested that all users comply
  44.     with the the wishes of the author/s as specified in the individual modules
  45.     and:
  46.         a) To leave the code in the public domain
  47.         b) Not distribute any modified or incomplete versions of this library
  48.  
  49.     New contribution and comments are welcome and hopefully there will be more
  50.     releases as the code evolves.
  51.  
  52.     Finally, do not trust this excuse for a manual if in doubt, as this code has
  53.     undergone several revisions. The place to get the answers is in the code
  54.     itself.
  55.  
  56. ╔═══════════════════════════════════════════════════════════════════════════╗
  57. ║ REQUIREMENTS                                                              ║
  58. ╚═══════════════════════════════════════════════════════════════════════════╝
  59.  
  60.     Minimum requirements
  61.         286 processor,
  62.         VGA,
  63.         Borland/Turbo Pascal v6.0/7.0
  64.  
  65. ╔═══════════════════════════════════════════════════════════════════════════╗
  66. ║ GENERAL FEATURES                                                          ║
  67. ╚═══════════════════════════════════════════════════════════════════════════╝
  68.  
  69.     Support for a number of 256 colour tweaked graphics mode resolutions
  70.     320x200 320x240 360x200 360x240 376x282 320x400 320x480 360x400 360x480
  71.     360x360 376x308 376x564
  72.  
  73.     Please note that some of the new resolutions best suit monitors with
  74.     adjustable vertical height.
  75.  
  76.     Virtual screens larger than the physical screen (memory permitting) that
  77.     can be panned at pixel resolution in all directions
  78.  
  79.     A split screen capability for status displays etc.
  80.  
  81.     Text functions supporting 8x8 and 8x14 ROM fonts and user defined fonts
  82.  
  83.     Support for page flipping
  84.  
  85.     Graphics primitives such as line and rectangle drawing functions and
  86.     of course bit block manipulation functions
  87.  
  88. ╔═══════════════════════════════════════════════════════════════════════════╗
  89. ║ BUILDING THE LIBRARIES                                                    ║
  90. ╚═══════════════════════════════════════════════════════════════════════════╝
  91.  
  92.     To compile XLIB just load it in the IDE and press F9. If you prefer the
  93.     command line compiler then just run TPC xlib.
  94.  
  95. ╔═══════════════════════════════════════════════════════════════════════════╗
  96. ║ USING THE LIBARY WITH YOUR PROGRAMS                                       ║
  97. ╚═══════════════════════════════════════════════════════════════════════════╝
  98.  
  99.     Using the XLIB library in your programs is simple. Just include the XLIB
  100.     unit in the uses statement at the beginning of your program which will make
  101.     all the procedures and functions composing the XLIB library available.
  102.  
  103. ╔═══════════════════════════════════════════════════════════════════════════╗
  104. ║ GLOBAL CONSTANTS AND VARIABLES                                            ║
  105. ╚═══════════════════════════════════════════════════════════════════════════╝
  106.  
  107.     Available X mode resolutions :
  108.         XMODE320x200 = 0
  109.         XMODE320x240 = 1
  110.         XMODE360x200 = 2
  111.         XMODE360x240 = 3
  112.         XMODE360x282 = 4
  113.         XMODE320x400 = 5
  114.         XMODE320x480 = 6
  115.         XMODE360x400 = 7
  116.         XMODE360x480 = 8
  117.         XMODE360x360 = 9
  118.         XMODE376x308 = 10
  119.         XMODE376x564 = 11
  120.  
  121.     Palette rotation direction direction :
  122.  
  123.         RBackward = 0
  124.         RForward  = 1
  125.  
  126.     Error constants :
  127.  
  128.         XModeInvalid = -1
  129.         Error        = 1
  130.         OK           = 0
  131.  
  132.  
  133.     InGraphics : byte -  Flag indicating that the xlib graphics system is
  134.              active. Set by function "xsetmode".
  135.  
  136.     CurrXMode : word  - If the xlib graphics system is active, contains the id
  137.              of the x mode. Set by function "xsetmode".
  138.              See also constants (i.e. XMODE320x200 ... )
  139.  
  140.     ScrnPhysicalByteWidth : word - Physical screen width in bytes. Set by
  141.              function "xsetmode"
  142.  
  143.     ScrnPhysicalPixelWidth - word - Physical screen width in pixels. Set by
  144.              function "xsetmode"
  145.  
  146.     ScrnPhysicalHeight : word - Physical screen height in pixels. Set by
  147.              function "xsetmode".
  148.  
  149.     ErrorValue : word - Contains error value. General use variable to
  150.              communicate the error status from several functions. The value
  151.              in this variable usually is only valid for the the last
  152.              function called that sets it.
  153.  
  154.     SplitScrnOffs : word - Offset in video ram of split screen. Set by
  155.              function "xsetsplitscrn". The value is only valid if a split
  156.              screen is active. See also global variable "SplitScrnActive".
  157.  
  158.     SplitScrnScanLine : word - Screen Scan Line the Split Screen starts at
  159.              initially when set by function "xsetsplitscrn". The value is only
  160.              valid if a split screen is active. See also global variable
  161.              "SplitScrnActive".This variable is not updated by "xhidesplitscrn",
  162.              "xadjustsplitscrn".
  163.  
  164.     SplitScrnVisibleHeight : word - The number of rows of the initial split
  165.              screen which are currently displayed. Modified by "xhidesplitscrn",
  166.              "xadjustsplitscrn" and "xshowsplitscrn".
  167.  
  168.     Page0Offs : word - Offset in video ram of main virtual screen. Initially
  169.              set by function "xsetmode" but is updated by functions
  170.              "xsetsplitscrn" and "xsetdoublebuffer".
  171.  
  172.     Page1Offs : word - Offset in video ram of second virtual screen. Set by
  173.              and only is valid after a call to "xsetdoublebuffer".
  174.  
  175.     ScrnLogicalByteWidth : word - Virtual screen width in bytes. Set by
  176.              function "xsetmode".
  177.  
  178.     ScrnLogicalPixelWidth : word - Virtual screen width in pixels. Set
  179.              by function "xsetmode".
  180.  
  181.     ScrnLogicalHeight : word - Virtual screen height in pixels. Set
  182.              initially by function "xsetmode" but is updated by functions
  183.              "xsetsplitscrn" and "xsetdoublebuffer".
  184.  
  185.     MaxScrollX : word - Max X pixel position of physical screen within
  186.              virtual screen. Set by function "xsetmode".
  187.  
  188.     MaxScrollY : word - Max Y position of physical screen within virtual
  189.              screen. Set initially by function "xsetmode" but is updated by
  190.              functions "xsetsplitscrn" and "xsetdoublebuffer".
  191.  
  192.     DoubleBufferActive : word - Indicates whether double-buffering is on. Set
  193.              by function "xsetdoublebuffer".
  194.  
  195.     VisiblePageIdx : word - Index number of current visible page. Initially
  196.              set by function "xsetdoublebuffer" but is updated by "xpageflip".
  197.              This variable is only used while double buffering is on.
  198.  
  199.     HiddenPageOffs : word - Offset of hidden page. Initially set by function
  200.              "xsetdoublebuffer" but is updated by "xpageflip". This variable
  201.              is only used while double buffering is on.
  202.  
  203.     VisiblePageOffs : word - Offset of visible page. Initially set by function
  204.              "xsetdoublebuffer" but is updated by "xpageflip". This variable
  205.              is only used while double buffering is on.
  206.  
  207.     NonVisualOffs : word - Offset of first byte of non-visual ram, the ram
  208.              that is available for bitmap storage etc. Set initially by function
  209.              "xsetmode" but is updated by functions "xsetsplitscrn" and
  210.              "xsetdoublebuffer".
  211.  
  212.     TopClip, BottomClip, LeftClip, RightClip : word - Define the clipping
  213.              rectangle for Linear and Video clipped bitmap put functions. Set
  214.              either manually or by "xsetcliprect". Note X coordinates are in
  215.              bytes as all clip functions clip to byte boundaries.
  216.  
  217.     PhysicalStartPixelX : word - X pixel Offset of physical (visible) screen
  218.              relative to the upper left hand corner (0,0) of the virtual screen.
  219.  
  220.     PhysicalStartByteX : word - X byte Offset of physical (visible) screen
  221.              relative to the upper left hand corner (0,0) of the virtual screen.
  222.  
  223.     PhysicalStartY : word - Y pixel Offset of physical (visible) screen
  224.              relative to the upper left hand corner (0,0) of the virtual screen.
  225.  
  226. ╔═══════════════════════════════════════════════════════════════════════════╗
  227. ║ EXPORTED PROCEDURES AND FUNCTIONS                                         ║
  228. ╚═══════════════════════════════════════════════════════════════════════════╝
  229.  
  230.     xsetmode
  231.     --------
  232.  
  233.         Function XSetMode( mode, WidthInPixels : word ) : word;
  234.  
  235.         mode          - The required mode as defined by the "Available X Mode
  236.                                         resolutions" set of defines in the xlib.h header file.
  237.         WidthInPixels - The required virtual screen width.
  238.         Returns       - The actual width in pixels of the allocated virtual
  239.                                         screen
  240.  
  241.     This function initialises the graphics system, setting the apropriate
  242.     screen resolution and allocating a virtual screen. The virtual screen
  243.     allocated may not necessarily be of the same size as specified in the
  244.     "WidthInPixels" parameter as it is rounded down to the nearest
  245.     multiple of 4.
  246.  
  247.     The function returns the actual width of the allocated virtual screen
  248.     in pixels if a valid mode was selected otherwise returns
  249.     XMODEINVALID.
  250.  
  251.     Saves virtual screen pixel width in "ScrnLogicalPixelWidth".
  252.     Saves virtual screen byte  width in "ScrnLogicalByteWidth".
  253.     Physical screen dimensions are set in "ScrnPhysicalPixelWidth".
  254.     "ScrnPhysicalByteWidth" and "ScrnPhysicalHeight". Other global variables
  255.     set are "CurrXMode","MaxScrollX", "MaxScrollY", "InGraphics".
  256.     The variable "SplitScrnScanline" is also initialized to zero.
  257.  
  258.     See also:
  259.          Available X Mode resolutions
  260.          What is Mode X
  261.  
  262.     xselectdefaultplane
  263.     -------------------
  264.  
  265.         Procedure XSelectDefaultPlane( plane : byte );
  266.  
  267.         Enables default Read/Write access to a specified plane
  268.  
  269.  
  270.     xsetsplitscreen
  271.     -----------------
  272.  
  273.         Procedure XSetSplitScreen( line : word );
  274.  
  275.         line - The starting scan line of the required split screen.
  276.  
  277.     This function activates Mode X split screen and sets starting scan line
  278.     The split screen resides on the bottom half of the screen and has a
  279.     starting address of A000:0000 in video RAM.
  280.  
  281.     It also Updates Page0Offs to reflect the existence of the split screen
  282.     region ie "MainScrnOffset" is set to the offset of the first pixel
  283.     beyond the split screen region. Other variable set are "Page1Offs" which
  284.     is set to the same value as "Page0Offs" (see graphics call sequence below),
  285.     "ScrnLogicalHeight","ScrnPhysicalHeight", "SplitScrnScanLine" and
  286.     "MaxScrollY".
  287.  
  288.     This function cannot be called after double buffering has been activated,
  289.     it will return an error. To configure your graphics environment the
  290.     sequence of graphics calls is as follows although either or both steps b
  291.     and c may be omitted:
  292.         a) xsetmode
  293.         b) xsetsplitscreen
  294.         c) xsetdoublebuffer
  295.     Thus when you call this function successfully, double buffering is not
  296.     active so "Page1Offs" is set to the same address as "Page0Offs".
  297.  
  298.     WARNING: If you use one of the high resolution modes (376x564 as an
  299.         extreme example) you may not have enough video ram for split screen
  300.         and double buffering options since VGA video RAM is restricted to
  301.         64K.
  302.  
  303.     See Also:
  304.         What is a Split Screen ?
  305.         What is double buffering ?
  306.  
  307.     xsetdoublebuffer
  308.     ----------------
  309.  
  310.     Function xsetdoublebuffer( PageHeight : word ) : word;
  311.  
  312.     PageHeight - The height of the two double buffering virtual screens.
  313.     Returns    - The closest possible height to the specified.
  314.  
  315.     This function sets up two double buffering virtual pages. "ErrorValue"
  316.     is set according to the success or failure of this command.
  317.  
  318.     Other variables set are:
  319.  
  320.         Page1Offs            -  Offset of second virtual page
  321.         NonVisualOffs        -  Offset of first non visible video ram byte
  322.         DoubleBufferActive   -  Flag
  323.         PageAddrTable        -  Table of Double buffering pages start offsets
  324.         ScrnLogicalHeight    -  Logical height of the double buffering pages
  325.         MaxScrollY           -  Max vertical start address of physical screen
  326.                                                         within the virtual screen
  327.  
  328.     WARNING: If you use one of the high resolution modes (376x564 as an
  329.         extreme example) you may not have enough video ram for split screen
  330.         and double buffering options since VGA video RAM is restricted to 64K.
  331.  
  332.     See Also:
  333.         What is double buffering ?
  334.  
  335.     xhidesplitscreen
  336.     ----------------
  337.  
  338.     Procedure XHideSplitScreen;
  339.  
  340.     This function hides an existing split screen by setting its starting
  341.     scan line to the last physical screen scan line.
  342.     "ScreenPhysicalHeight" is adjusted but the "SplitScreenScanLine" is not
  343.     altered as it is required for restoring the split screen at a later stage.
  344.  
  345.     WARNING: Only to be used if SplitScrnLine has been previously called
  346.          Disabled for mode 5-11 (320x400-376x564). The memory for
  347.          the initial split screen is reserved and the size limitations
  348.          of these modes means any change in the split screen scan line
  349.          will encroach on the split screen ram
  350.          Update: Now disabled for these modes
  351.  
  352.     See Also:
  353.  
  354.         What is a split screen ?
  355.  
  356.     xshowsplitscreen
  357.     ----------------
  358.  
  359.     Procedure XShowSplitScreen;
  360.  
  361.     Restores split screen start scan line to the initial split screen
  362.     starting scan line as set by "SplitScrnScanLine".
  363.     "ScreenPhysicalHeight" is adjusted.
  364.  
  365.     WARNING: Only to be used if SplitScrnLine has been previously called
  366.          Disabled for mode 4-10 (320x400-376x564). The memory for
  367.          the initial split screen is reserved and the size limitations
  368.          of these modes means any change in the split screen scan line
  369.          will encroach on the split screen ram
  370.  
  371.  
  372.     XAdjustSplitScreen
  373.     ------------------
  374.  
  375.     Procedure XAdjustSplitScreen( line : word );
  376.  
  377.     line - The scan line at which the split screen is to start.
  378.  
  379.     Sets the split screen start scan line to a new scan line. Valid scan lines
  380.     are between the initial split screen starting scan line and the last
  381.     physical screen scan line. "ScreenPhysicalHeight" is also adjusted.
  382.  
  383.     WARNING: Only to be used if SplitScrnLine has been previously called
  384.          Disabled for mode 4-10 (320x400-376x564). The memory for
  385.          the initial split screen is reserved and the size limitations
  386.          of these modes means any change in the split screen scan line
  387.          will encroach on the split screen ram
  388.  
  389.     XSetStartAddr
  390.     -------------
  391.  
  392.     Procedure XSetStartAddr( X, Y : word );
  393.  
  394.         X,Y - coordinates of top left corner of physical screen within current
  395.                     virtual screen.
  396.  
  397.     Set Mode X non split screen physical start address within current virtual
  398.     page.
  399.  
  400.     X must not exceed (Logical screen width - Physical screen width)
  401.     ie "MaxScrollX" and Y must not exceed (Logical screen height -
  402.     Physical screen height) ie "MaxScrollY"
  403.  
  404.     XPageFlip
  405.     ---------
  406.  
  407.     Procedure XPageFlip( X, Y : word );
  408.  
  409.         X,Y - coordinates of top left corner of physical screen within the
  410.                     the hidden virtual screen if double buffering is active, or
  411.                     the current virtual screen otherwise.
  412.  
  413.     Sets the physical screen start address within currently hidden virtual
  414.     page and then flips pages. If double buffering is not active then this
  415.     function is functionally equivalent to "xsetstartaddr".
  416.  
  417.     X must not exceed (Logical screen width - Physical screen width)
  418.     ie "MaxScrollX" and Y must not exceed (Logical screen height -
  419.     Physical screen height) ie "MaxScrollY"
  420.  
  421.     xtextmode
  422.     ---------
  423.  
  424.     Procedure xtextmode;
  425.  
  426.     Disables graphics mode.
  427.  
  428.     xsetcliprect
  429.     ------------
  430.  
  431.     Procedure xsetcliprect( left, top, right, bottom : word );
  432.  
  433.     Defines the clipping rectangle for clipping versions of planar and video
  434.     bitmap puts.
  435.  
  436.     NOTE: Compiled bitmaps cannot be clipped.
  437.  
  438.     xputpix
  439.     -------
  440.  
  441.     Procedure xputpix( X, Y, PageOffset, Color : word );
  442.  
  443.     Draw a point of specified colour at coordinates X,Y
  444.     within the virtual page starting at offset PageOffset.
  445.  
  446.     xgetpix
  447.     ---------
  448.  
  449.     Function xgetpix( X, Y, PageBase : word ) : word;
  450.  
  451.     Read a point of at coordinates X,Y within the virtual page starting
  452.     at offset PageOffset.
  453.  
  454.     xrectpattern
  455.     ------------
  456.  
  457.     Procedure xrectpattern( StartX, StartY,
  458.                             EndX, EndY, PageBase : word;
  459.                             var Pattern );
  460.  
  461.     StartX,StartY - Coordinates of upper left hand corner of rectangle
  462.     EndX,EndY     - Coordinates of lower right hand corner of rectangle
  463.     PageBase      - Offset of virtual screen
  464.     *Pattern      - Pointer to the user defined pattern (16 bytes)
  465.  
  466.  
  467.     Mode X rectangle 4x4 pattern fill routine.
  468.  
  469.     Upper left corner of pattern is always aligned to a multiple-of-4
  470.     row and column. Works on all VGAs. Uses approach of copying the
  471.     pattern to off-screen display memory, then loading the latches with
  472.     the pattern for each scan line and filling each scan line four
  473.     pixels at a time. Fills up to but not including the column at EndX
  474.     and the row at EndY. No clipping is performed.
  475.  
  476.     Based on code originally published in DDJ Mag by M. Abrash
  477.  
  478.     Warning the VGA memory locations PATTERNBUFFER (A000:FFFc) to
  479.     A000:FFFF are reserved for the pattern buffer
  480.  
  481.  
  482.     See Also:
  483.         Doctor Dobbs Journal references.
  484.  
  485.  
  486.     xrectpatternclipped
  487.     -------------------
  488.  
  489.     As above but clipped.
  490.  
  491.  
  492.     xcpvidrect
  493.     ----------
  494.  
  495.     Procedure xcpvidrect( SourceStartX, SourceStartY,
  496.                             SourceEndX, SourceEndY,
  497.                             DestStartX, DestStartY,
  498.                             SourcePageBase, DestPageBase,
  499.                             SourceBitmapWidth, DestBitmapWidth : word );
  500.  
  501.     StartX,StartY- Coordinates of upper left hand corner of source rectangle
  502.     EndX,EndY    - Coordinates of lower right hand corner of source rectangle
  503.     DestStartX,DestStartY - Coordinates of rectangle destination
  504.     SourcePageBase        - source rectangle page offset
  505.     DestPageBase          - destination rectangles page offset
  506.     SourceBitmapWidth     - width of bitmap within the source virtual screen
  507.                 containing the source rectangle
  508.     DestBitmapWidth       - width of bitmap within the dest. virtual screen
  509.                 containing the destination rectangle
  510.  
  511.     Mode X display memory to display memory copy
  512.     routine. Left edge of source rectangle modulo 4 must equal left edge
  513.     of destination rectangle modulo 4. Works on all VGAs. Uses approach
  514.     of reading 4 pixels at a time from the source into the latches, then
  515.     writing the latches to the destination. Copies up to but not
  516.     including the column at SrcEndX and the row at SrcEndY. No
  517.     clipping is performed. Results are not guaranteed if the source and
  518.     destination overlap.
  519.  
  520.  
  521.     Based on code originally published in DDJ Mag by M. Abrash
  522.  
  523.     See Also:
  524.         Doctor Dobbs Journal references.
  525.  
  526.     xshiftrect
  527.     ----------
  528.  
  529.     Procedure xshiftrect ( SrcLeft, SrcTop, SrcRight, SrcBottom,
  530.                             DestLeft, DestTop, ScreenOffs : word );
  531.  
  532.     SrcLeft, SrcTop - Coordinates of upper left hand corner of rectangle
  533.     SrcRight, SrcBottom - Coordinates of lower right hand corner of rectangle
  534.     DestLeft, DestTop - Coordinates of upper left corner of destination
  535.     ScreenOffs    - Offset of virtual screen
  536.  
  537.     This function copies a rectangle of VRAM onto another area of VRAM,
  538.     even if the destination overlaps with the source.  It is designed
  539.     for scrolling text up and down, and for moving large areas of screens
  540.     around in tiling systems.  It rounds all horizontal coordinates to
  541.     the nearest byte (4-column chunk) for the sake of speed.  This means
  542.     that it can NOT perform smooth horizontal scrolling.  For that,
  543.     either scroll the whole screen (minus the split screen), or copy
  544.     smaller areas through system memory using the functions in the
  545.     XPBITMAP module.
  546.  
  547.     SrcRight is rounded up, and the left edges are rounded down, to
  548.     ensure that the pixels pointed to by the arguments are inside the
  549.     the rectangle.  That is, SrcRight is treated as (SrcRight+3) >> 2,
  550.     and SrcLeft as SrcLeft >> 2.
  551.  
  552.     The width of the rectangle in bytes (width in pixels / 4)
  553.     cannot exceed 255.
  554.  
  555. ╔═══════════════════════════════════════════════════════════════════════════╗
  556. ║ Palette functions for VGA 256 color modes                                 ║
  557. ╚═══════════════════════════════════════════════════════════════════════════╝
  558.  
  559.     All the functions in this module operate on two variations of the
  560.     palette buffer, the raw and annotated buffers.
  561.  
  562.     All those functions ending in "raw" operate on the following palette
  563.     structure:
  564.  
  565.         r0,g0,b0,r1,g1,b1,...rn,gn,bn : byte;
  566.  
  567.     No reference to the starting colour index or number of colours stored
  568.     is contained in the structure.
  569.  
  570.     All those functions ending in "struc" operate on the following palette
  571.     structure:
  572.  
  573.         c, n, r0,g0,b0,r1,g1,b1,...rn,gn,bn : byte;
  574.  
  575.     where c is the starting colour and n is the number of colours stored
  576.  
  577.  
  578.     WARNING : There is no validity checking in these functions. The onus is
  579.                         on the user to supply valid parameters to the functions.
  580.  
  581.  
  582.     xgetpalraw
  583.     ----------
  584.  
  585.     Procedure xgetpalraw( var pal; numcolrs, startindex : word );
  586.  
  587.     Read DAC palette into raw buffer with interrupts disabled
  588.  
  589.     WARNING: Memory for the palette buffers must all be pre-allocated.
  590.  
  591.     xgetpalstruc
  592.     ------------
  593.  
  594.     Procedure xgetpalstruc( var pal, numcolrs, startindex : word );
  595.  
  596.     Read DAC palette into annotated type buffer with interrupts disabled
  597.  
  598.     WARNING: memory for the palette buffers must all be pre-allocated
  599.  
  600.     xputpalraw
  601.     ----------
  602.  
  603.     Procedure xputpalraw( var pal; numcolrs, startindex : word );
  604.  
  605.     Write DAC palette from raw buffer with interrupts disabled
  606.  
  607.     xputpalstruc
  608.     ------------
  609.  
  610.     Procedure xputpalstruc( var pal );
  611.  
  612.     Write DAC palette from annotated type buffer with interrupts disabled
  613.  
  614.     xsetrgb
  615.     -------
  616.  
  617.     Procedure xsetrgb( color, redc, greenc, bluec : byte );
  618.  
  619.     Set the RGB components of a vga color
  620.  
  621.     xrotpalstruc
  622.     ------------
  623.  
  624.     Procedure xrotpalstruc( var pal; direction : word );
  625.  
  626.     Rotate annotated palette buffer entries. 
  627.     Direction 0 = backward, 1 = forward.
  628.  
  629.     xrotpalraw
  630.     ----------
  631.  
  632.     Procedure xrotpalraw( var pal; direction, numcolrs : word );
  633.  
  634.     Rotate a raw palette buffer. 
  635.     Direction 0 = backward, 1 = forward.
  636.  
  637.     xputcontrastpalstruc
  638.     --------------------
  639.  
  640.     Procedure xputcontrastpalstruc( var pal; intensity : byte );
  641.  
  642.     Write DAC palette from annotated type buffer with specified intensity
  643.     adjustment (ie palette entries are decremented where possible by
  644.     "intensity" units).
  645.  
  646.     Designed for fading in or out a palette without using an intermediate
  647.     working palette buffer ! (Slow but memory efficient ... OK for small
  648.     pal strucs)
  649.  
  650.  
  651.     xtransposepalstruc
  652.     ------------------
  653.  
  654.     Procedure xtransposepalstruc( var pal; StartColor : word );
  655.  
  656.     Write DAC palette from annotated type buffer with interrupts disabled
  657.     starting at a new palette index.
  658.  
  659.  
  660.     xcpcontrastpalstruc
  661.     -------------------
  662.  
  663.     Function xcpcontrastpalstruc( var srcpal, destpal; Intensity : byte );
  664.  
  665.     Copy one annotated palette buffer to another making the intensity
  666.     adjustment. Used in fading in and out fast and smoothly.
  667.  
  668.     xline
  669.     -----
  670.  
  671.     Procedure xline( x0, y0, x1, y1, color, PageBase : word );
  672.  
  673.     Draw a line with the specified end points in the page starting at
  674.     offset "PageBase".
  675.  
  676.     No Clipping is performed.
  677.  
  678. ╔═══════════════════════════════════════════════════════════════════════════╗
  679. ║ FONTS                                                                     ║
  680. ╚═══════════════════════════════════════════════════════════════════════════╝
  681.  
  682.      FONT8x8  = 0
  683.      FONT8x15 = 1
  684.      FONTUSER = 2
  685.  
  686.     EXPORTED VARIABLES
  687.  
  688.         NOTE: All variables are read only. I you modify them the results may
  689.         be unpredictable.
  690.  
  691.         CharHeight - byte - Height of current inbuilt character set
  692.  
  693.         CharWidth  - byte - Width of current inbuilt character set
  694.  
  695.         FirstChar  - byte - First character of current inbuilt character set
  696.  
  697.         UserCharHeight - byte - Height of current user character set
  698.  
  699.         UserCharWidth - byte - Width of current user character set
  700.  
  701.         UserFirstCh - byte - First character of current user character set
  702.  
  703.  
  704.     xtextinit
  705.     ---------
  706.  
  707.     Procedure xtextinit;
  708.  
  709.     Initializes the Mode X text driver and sets the default font (VGA ROM 8x8)
  710.  
  711.     xsetfont
  712.     --------
  713.  
  714.     Procedure xsetfont( FontId : word );
  715.  
  716.     Select the working font where 0 = VGA ROM 8x8, 1 = VGA ROM 8x14
  717.     2 = User defined bitmapped font.
  718.  
  719.     WARNING: A user font must be registered before setting FontID 2
  720.  
  721.     See Also:
  722.  
  723.         Font constants.
  724.  
  725.     xregisteruserfont
  726.     -----------------
  727.  
  728.     Procedure xregisteruserfont( var UserFontPtr );
  729.  
  730.     Register a user font for later selection. Only one user font can be
  731.     registered at any given time. Registering a user font deregisters the
  732.     previous user font. User fonts may be at most 8 pixels wide.
  733.  
  734.     USER FONT STRUCTURE
  735.  
  736.     Word:  ascii code of first char in font
  737.     Byte:  Height of chars in font
  738.     Byte:  Width of chars in font
  739.     n*h*Byte: the font data where n = number of chars and h = height
  740.         of chars
  741.  
  742.     WARNING: The onus is on the program to ensure that all characters
  743.          drawn whilst this font is active, are within the range of
  744.          characters defined.
  745.  
  746.     xputchar
  747.     --------
  748.  
  749.     Function xputchar( ch : char; X, Y, PgOffs, Color : word ) : word;
  750.  
  751.     Draw a text character at the specified location with the specified
  752.     color.
  753.  
  754.     ch       -  char to draw
  755.     x,y      -  screen coords at which to draw ch
  756.     ScrnOffs -  Starting offset of page on whih to draw
  757.     Color    -  Color of the text
  758.     Returns the width of the character.
  759.  
  760.     WARNING: InitText must be called before using this function
  761.  
  762.  
  763.     xprintf
  764.     -------
  765.  
  766.     Procedure xprintf( x, y, ScrnOffs, color : word; s : string );
  767.  
  768.     x,y      -  screen coords at which to draw ch
  769.     ScrnOffs -  Starting offset of page on whih to draw
  770.     Color    -  Color of the text
  771.     s        -  Text to be displayed
  772.  
  773.     xbgprintf
  774.     ---------
  775.  
  776.     Procedure xbgprintf( x, y, ScrnOffs, fgcolor, bgcolor : word; s: string );
  777.  
  778.     x,y      -  screen coords at which to draw ch
  779.     ScrnOffs -  Starting offset of page on whih to draw
  780.     fgcolor  -  Color of the text foreground
  781.     bgcolor  -  Color of the text background
  782.     s        -  String to be displayed   
  783.  
  784.     xgetcharwidth
  785.     -------------
  786.  
  787.     Function xgetcharwidth( ch :char ) : word;
  788.  
  789.     ch - character to get width of
  790.  
  791. ╔═══════════════════════════════════════════════════════════════════════════╗
  792. ║ PLANAR BITMAPS                                                            ║
  793. ╚═══════════════════════════════════════════════════════════════════════════╝
  794.  
  795.     Planar bitmaps as used by these functions have the following structure:
  796.  
  797.     byte 0             The bitmap width in bytes (4 pixel groups) range 1..255
  798.     byte 1             The bitmap height in rows range 1..255
  799.     byte 2..n1         The plane 0 pixels width*height bytes
  800.     byte n1..n2        The plane 1 pixels width*height bytes
  801.     byte n2..n3        The plane 2 pixels width*height bytes
  802.     byte n3..n4        The plane 3 pixels width*height bytes
  803.  
  804.     These functions provide the fastest possible bitmap blts from system ram
  805.     to video and further, the single bitmap is applicable to all pixel
  806.     alignments. The masked functions do not need separate masks since all non
  807.     zero pixels are considered to be masking pixels, hence if a pixel is 0 the
  808.     corresponding screen destination pixel is left unchanged.
  809.  
  810.     xputmaskedpbm
  811.     -------------
  812.  
  813.     Procedure xputmaskedpbm( X, Y, ScrnOffs : word; var Bitmap );
  814.  
  815.     Mask write a planar bitmap from system ram to video ram. All zero source
  816.     bitmap bytes indicate destination byte to be left unchanged.
  817.  
  818.     Source Bitmap structure:
  819.  
  820.     Width, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  821.     Bitmap data (plane 2)..,Bitmap data (plane 3)..
  822.  
  823.     NOTE: width is in bytes ie lots of 4 pixels
  824.  
  825.     LIMITATIONS: No clipping is supported
  826.                  Only supports bitmaps with widths which are a multiple of
  827.                  4 pixels
  828.  
  829.     See BITMAP TOOLS for linear <-> planar bitmap conversion
  830.          functions.
  831.  
  832.     xputpbm
  833.     -------
  834.  
  835.     Procedure xputpbm( X, Y, ScrnOffs : word; var Bitmap );
  836.  
  837.     Write a planar bitmap from system ram to video ram.
  838.  
  839.     Source Bitmap structure:
  840.  
  841.     Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  842.     Bitmap data (plane 2)..,Bitmap data (plane 3)..
  843.  
  844.     NOTE: width is in bytes ie lots of 4 pixels
  845.  
  846.     LIMITATIONS: No clipping is supported
  847.                  Only supports bitmaps with widths which are a multiple of
  848.                  4 pixels
  849.  
  850.  
  851.     See BITMAP TOOLS for linear <-> planar bitmap conversion
  852.          functions.
  853.  
  854.     xgetpbm
  855.     -------
  856.  
  857.     Procedure xgetpbm( X, Y : word; Bw, Bh : byte; 
  858.                             ScrnOffs : word; var Bitmap );
  859.  
  860.     Read a planar bitmap to system ram from video ram.
  861.  
  862.     Source Bitmap structure:
  863.  
  864.     Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  865.     Bitmap data (plane 2)..,Bitmap data (plane 3)..
  866.  
  867.     NOTE: width is in bytes ie lots of 4 pixels
  868.  
  869.     LIMITATIONS: No clipping is supported
  870.                  Only supports bitmaps with widths which are a multiple of
  871.                  4 pixels
  872.  
  873. ╔═══════════════════════════════════════════════════════════════════════════╗
  874. ║ CLIPPED PLANAR BITMAPS                                                    ║
  875. ╚═══════════════════════════════════════════════════════════════════════════╝
  876.  
  877.     There are three variations of the previous procedures identified by the 
  878.     three function name extensions: clipx, clipy clipxy.
  879.     Because speed is critical in games programming you do not want to be
  880.     checking for clipping if not necessary thus for sprites that move only
  881.     horizontally you would use the clipx version of the put function,
  882.     for sprites that move vertically you would use the clipy version and for
  883.     sprites that move both directions you would use the clipxy version.
  884.     Keep in mind also that the clipping components of these functions assume
  885.     that the clipping rectangle is equal to or larger than the size of the
  886.     bitmap ie. if a bitmap is top clipped, it is assumed that the bitmap's
  887.     bottom is not also clipped. Similarly with horizontal clipping.
  888.  
  889.     Note: performance in decreasing order is as follows :
  890.         clipy,clipx,clipxy with masked puts being slower than unmasked
  891.             puts
  892.  
  893.     Horizontal clipping is performed to byte boundaries (4 pixels) rather than
  894.     pixels. This allows for the fastest implementation of the functions. It is
  895.     not such a handicap because for one, your screen width a multiple of 4
  896.     pixels wide and  for most purposes it is the screen edges that form the
  897.     clipping rectangle.
  898.  
  899.     Following is an example of setting a clipping rectangle to the logical
  900.     screen edges:
  901.  
  902.     xsetcliprect(0,0,ScrnLogicalByteWidth,ScrnLogicalHeight)
  903.  
  904.     xputpbmclipx
  905.     ------------
  906.     xputpbmclipy
  907.     ------------
  908.     xputpbmclipxy
  909.     -------------
  910.     xputmaskedpbmclipx
  911.     ------------------
  912.     xputmaskedpbmclipy
  913.     ------------------
  914.     xputmaskedpbmclipxy
  915.     -------------------
  916.  
  917.     For a detailed description of parameters etc. see equivalent PLANAR
  918.     BITMAP procedures
  919.  
  920. ╔═══════════════════════════════════════════════════════════════════════════╗
  921. ║ COMPILED BITMAPS                                                          ║
  922. ╚═══════════════════════════════════════════════════════════════════════════╝
  923.  
  924.                  The Care and Feeding of Compiled Masked Blits
  925.                  by Matthew MacKenzie
  926.  
  927. The procedures are dedicated to compiled bitmaps :
  928.     o  xcompilebitmap compiles your bitmap into native code which writes
  929.          to the VGA screen in an X mode.
  930.     o  xputcbitmap converts X and Y coordinates into a location on the
  931.          screen, sets up the necessary VGA registers, and executes the compiled
  932.          bitmap as a subroutine.
  933.     o  xsizeofcbitmap takes a planar bitmap and returns an integer equal to
  934.          the size of the compiled bitmap which the planar bitmap would produce.
  935.          It is essentially a lobotomized version of xcompilebitmap, with all
  936.          the code generation replaced with a size counter.
  937.  
  938.         Xcompilebitmap scans through a source bitmap and generates 8086
  939. instructions to plot every nonzero pixel.  It is designed to be used
  940. before the action begins rather than on-the-fly.  The compiled bitmap
  941. contains no branches, and no reference to the zero (transparent) pixels.
  942. Where two pixels are exactly four columns apart they are plotted with a
  943. single 16-bit store, and the VGA MAPMASK register will be set at most
  944. four times.  As a result your bitmap may run several times faster than a
  945. traditional memory-to-VGA masked blit routine.
  946.         There is no way to perform clipping on these bitmaps, or to plot a
  947. pixel of color zero.
  948.         Xcompilebitmap works with bitmaps in the standard Xlib planar bitmap
  949. format.  On a time scale of 60 frames per second, it is actually relatively
  950. slow.  Since a compiled bitmap is relocatable you may just want to have it
  951. saved to disk, and not include the source bitmap in your program at all.
  952.         The source bitmap format is an array of bytes, a little like this:
  953.  
  954. eye : array[0..29] of byte = 
  955.     (  4, 7,  { four byte columns across, seven rows tall }
  956.          0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0,
  957.          0, 0, 9, 9, 1, 1, 1, 4, 4, 9, 9, 0, 0, 0, 0, 0,
  958.          0, 9, 9, 1, 2, 0, 0, 4, 4, 1, 9, 9, 0, 0, 0, 0,
  959.          9, 9, 9, 1, 0, 0, 0, 0, 1, 1, 9, 9, 9, 0, 0, 0,
  960.          0, 9, 9, 1, 2, 0, 0, 2, 1, 1, 9, 9, 0, 0, 0, 0,
  961.          0, 0, 9, 9, 1, 1, 1, 1, 1, 9, 9, 0, 0, 0, 0, 0,
  962.          0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0 );
  963.  
  964.         This is actually a linear bitmap, which is the wrong format for
  965. compilation, but is easier on human eyes.  Use the BITMAP TOOLS procedures
  966. to convert linear bitmaps into planar bitmaps, and vice-versa.
  967.         To compile this image for a mode 360 pixels (90 byte columns) across:
  968.  
  969. planareye : array[0..29] of byte;
  970. EyeSize : word;
  971. CompiledEye : pointer;
  972.  
  973. xbmtopbm( eye, planareye);
  974. EyeSize := xsizeofcbitmap(planareye);
  975. GetMem(CompiledEye, EyeSize);
  976. xcompilebitmap(90, planareye, CompiledEye^);
  977.  
  978.         Notice that both buffers must exist beforehand.  Since xcompilebitmap
  979. returns the size of the compiled code, in bytes, you can reallocate the
  980. bitmap immediately to the right size if using xsizeofxbitmap seems
  981. inconvenient (reallocation may even be faster, though using the function is
  982. cleaner).  The pointers are 32-bit because compiled bitmaps take so much
  983. space: they are at one end of the speed-versus-memory spectrum.  A good
  984. rule of thumb is to allocate (3.5 x buffer-height x buffer-width) + 25
  985. bytes (rounding up ;-), then pare your bitmap down when you find out how
  986. much space you've actually used.
  987.     Since the compiled bitmap has to fit within one segment of memory, it
  988. cannot contain more than about 19,000 pixels.  This will not be a
  989. limitation for most sane programmers.  If you are not a sane programmer try
  990. splitting your huge, unwieldy image up into smaller parts -- you can use
  991. the same gigantic bitmap if you divide it into horizontal slices for
  992. compilation.  For that matter, dividing the source up that way will let
  993. you use a source bitmap large than 64K, which is an even sicker idea...
  994.         Back to business.  A bitmap is compiled for only one width of screen.
  995. If you are using a logical screen larger than your physical screen, call
  996. the bitmap compiler with the logical width -- the important thing is the
  997. number of bytes per line.  Notice that you do not have to be in a graphics
  998. mode to use this routine.  This allows you to develop and compile bitmaps
  999. separately, with whatever utility programs you might cook up.
  1000.  
  1001.         The final function is xputcbitmap.  To plot our eye at (99,4), on
  1002. the page which starts at location 0:
  1003. xputcbitmap(99, 4, 0, CompiledEye);
  1004.     This function depends on the global variable ScrnLogicalByteWidth from
  1005. the module XMAIN, which should be the same number as the column parameter
  1006. you used to compile your bitmap.
  1007.         The XCBITMAP module supports memory-to-VGA blits only.  Xlib also
  1008. includes non-masking routines which can quickly save and restore the
  1009. background screen behind your bitmap, using fast string operations.
  1010.  
  1011.      This module is part of the Xlib package, and is in the public domain.
  1012. If you write something which uses it, though, please send me a copy as a
  1013. courtesy -- if for no other reason so I can tilt my chair back and reflect
  1014. that it may have been worth the trouble after all.
  1015.  
  1016. The included program DEMO2.C demonstrates the performance difference
  1017. between planar bitmap masked blits and compiled bitmap blits.
  1018.  
  1019.     xcompilepbm
  1020.     -----------
  1021.     xsizeofcpbm
  1022.     -----------
  1023.  
  1024.     Identical to the previous ones, but they work on PBMs
  1025.  
  1026. ╔═══════════════════════════════════════════════════════════════════════════╗
  1027. ║ VIDEO BITMAPS                                                             ║
  1028. ╚═══════════════════════════════════════════════════════════════════════════╝
  1029.  
  1030. The VIDEO BITMAPS procedures implement yet another type of bitmap to 
  1031. complement planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder 
  1032. car is analagous to planar bitmaps, that is thrifty on memory consumption but 
  1033. low performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers
  1034. that really fly, then VRAM based bitmaps are the 6 cylinder modest performers
  1035. with acceptable memory consumption.
  1036.  
  1037. To summarise their selling points, VBM's are moderately fast with fair memory
  1038. consumption, and unlike compiled bitmaps, can be clipped. The disadvantages
  1039. are that they are limited by the amount of free video ram and have a complex
  1040. structure.
  1041.  
  1042. The VRAM bitmap format is rather complex consisting of components stored in
  1043. video ram and components in system ram working together. This complexity
  1044. necessitates the existence of a creation function "xmakevbm" which takes
  1045. an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).
  1046.  
  1047. VBM structure:
  1048.  
  1049.             word  0   Size          Total size of this VBM structure in bytes
  1050.             word  1   ImageWidth    Width in bytes of the image (for all alignments)
  1051.             word  2   ImageHeight   Height in scan lines of the image
  1052.  
  1053.             word  3 Alignment 0  ImagePtr   Offset in VidRAM of this aligned image
  1054.      +--word  4              MaskPtr    Offset (within this structure's DS) of
  1055.      |   .                               alignment masks
  1056.      |   .
  1057.      |   .
  1058.      |  word  9 Alignment 3  ImagePtr   Offset in VidRAM of this aligned image
  1059.     +|--word 10              MaskPtr    Offset (within this structure's DS) of
  1060.     ||                                   alignment masks
  1061.     ||
  1062.     |+->byte 21 (word 11)                -------+-- Image masks for alignment 0
  1063.     |   .                                       |
  1064.     |   .                                       |
  1065.     |   byte  21 + ImageWidth*ImageHeight  -----+
  1066.     |
  1067.     |   .
  1068.     |   . (similaly for alignments 1 - 2 )
  1069.     |   .
  1070.     |
  1071.     +-->byte  21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3
  1072.             .                                       |
  1073.             .                                       |
  1074.             byte  21 + 4*(ImageWidth*ImageHeight) --+
  1075.  
  1076.             .
  1077.             .
  1078.             << Similarly for alignments 2 and 3 >>
  1079.             .
  1080.             .
  1081.             byte 21 + 4*(ImageWidth*ImageHeight)
  1082.     -------------
  1083.  
  1084.     (And dont forget the corresponding data in video ram)
  1085.  
  1086. You can see for yourself the complexity of this bitmap format. The image
  1087. is stored in video ram in its 4 different alignments with pointers to these
  1088. alignments in the VBM. Similarly there are 4 alignments of the corresponding
  1089. masks within the VBM itself (towards the end). The mask bytes contain the
  1090. plane settings for the corresponding video bytes so that one memory move can
  1091. move up to 4 pixels at a time (depending on the mask settings) using the
  1092. VGA's latches, theoretically giving you a 4x speed improvement over
  1093. conventional blits like the ones implemented in "XPBITMAP". In actual fact
  1094. its anywhere between 2 and 3 due to incurred overheads.
  1095.  
  1096. These bitmaps are more difficult to store in files than PBM'S and CBM's but
  1097. still posible with a bit of work, so do not dismiss these as too difficult
  1098. to use. Consider all the bitmap formats carefully before deciding on which
  1099. to use. There may even be situations that a careful application of all three
  1100. types would be most effective ie. compiled bitmaps for Background tiles and
  1101. the main game character (which never need clipping), VRAM based bitmaps for
  1102. the most frequently occuring (oponent, alien etc) characters which get
  1103. clipped as they come into and leave your current location and planar bitmaps
  1104. for smaller or less frequently encountered characters.
  1105.  
  1106.     xmakevbm
  1107.     --------
  1108.  
  1109.     Function xmakevbm( var lbm; var VramStart : word ) : pointer;
  1110.  
  1111.     Create the VBM from the given linear bitmap and place the image alignments
  1112.     in video ram starting at the offset in the variable pointed to by
  1113.     "VramStart". "VramStart" is then updated to point to the next free VRAM byte
  1114.     (just after the last byte of the image alignments). Usually you will point
  1115.     "VramStart" to "NonVisualOffs".
  1116.  
  1117.      lbm         Pointer to the input linear bitmap
  1118.      VramStart   Pointer to variable containing Offset of first free VRAM byte
  1119.  
  1120.      xputmaskedvbm
  1121.      -------------
  1122.  
  1123.      C Prototype: extern int xputmaskedvbm(int X, int Y, word ScrnOffs,
  1124.                 byte far * VBitmap);
  1125.  
  1126.      Draw a VRAM based bitmap at (X,Y) relative to the screen with starting
  1127.      offset "ScrnOffs".
  1128.  
  1129.      Returns 1 if clipped image is fully clipped (ie no portion of it
  1130.      appears on the screen) otherwise it returns 0
  1131.  
  1132.      xputmaskedvbmclipx
  1133.      ------------------
  1134.      xputmaskedvbmclipy
  1135.      ------------------
  1136.      xputmaskedvbmclipxy
  1137.      -------------------
  1138.  
  1139.          Clipping versions of "xputmaskedvbm".
  1140.  
  1141. ╔═══════════════════════════════════════════════════════════════════════════╗
  1142. ║ MOUSE ROUTINES                                                            ║
  1143. ╚═══════════════════════════════════════════════════════════════════════════╝
  1144.  
  1145. These procedures implement very basic mouse handling functions. The way
  1146. in which they operate is by installing an event handler function during
  1147. initialization which subsequently intercepts and processes mouse events and
  1148. automatically updates status variables such as mouse position and button
  1149. pressed status. It does not support the full functionality of:
  1150.  
  1151.     SPLIT SCREENS
  1152.     SCROLLED WINDOWS
  1153.     VIRTUAL WINDOWS
  1154.  
  1155. This was done to primarily prevent unecessary impedences to performance,
  1156. since the mouse handler function has the potential to degrade performance.
  1157. It also saves me alot of coding which I was too lazy to do.
  1158.  
  1159. Programs communicate with the mouse driver as with other devices, through
  1160. an interrupt vector namely 33h. On generating an interrupt, the mouse driver
  1161. expects a function number in AX and possibly other parameters in other
  1162. registers and returns information via the registers. A brief description
  1163. of the mouse functions follows:
  1164.  
  1165.                 --------------------------------------
  1166.  
  1167.                 MS Mouse Driver Functions
  1168.  
  1169.                 Mouse Initialization                 0
  1170.                 Show Cursor                          1
  1171.                 Hide Cursor                          2
  1172.                 Get Mouse Position & Button Status   3
  1173.                 Set Mouse Cursor Position            4
  1174.                 Get Button Press Information         5
  1175.                 Get Button Release Information       6
  1176.                 Set Min/Max Horizontal Position      7
  1177.                 Set Min/Max Vertical Position        8
  1178.                 Define Graphics Cursor Block         9
  1179.                 Define Text Cursor                  10
  1180.                 Read Mouse Motion Counters          11
  1181.                 Define Event Handler                12
  1182.                 Light Pen Emulation Mode ON         13
  1183.                 Light Pen Emulation Mode OFF        14
  1184.                 Set Mouse Mickey/Pixel Ratio        15
  1185.                 Conditional Hide Cursor             16
  1186.                 Set Double-Speed Threshold          19
  1187.                 --------------------------------------
  1188.  
  1189. In practice only afew of these functions are used and even fewer when the
  1190. mouse status is monitored by an event handler function such as is used in
  1191. this module.
  1192.  
  1193. The most important thing to note when using the mouse module is that the
  1194. mouse event handler must be removed before exiting the program. It is a good
  1195. idea to have an exit function and include the line "xmouseremove" along with 
  1196. any other pre-exit cleanup code.
  1197.  
  1198.  
  1199.     EXPORTED VARIABLES
  1200.  
  1201.      MouseInstalled    - word - Indicates whether mouse handler installed
  1202.      MouseHidden       - word - Indicates whether mouse cursor is hidden
  1203.      MouseButtonStatus - word - Holds the mouse button status
  1204.      MouseX            - word - Current X position of mouse cursor
  1205.      MouseY            - word - Current Y position of mouse cursor
  1206.      MouseFrozen       - word - Disallows position updates if TRUE
  1207.      MouseColor        - byte - The mouse cursors colour
  1208.  
  1209.     xmouseinit
  1210.     ----------
  1211.  
  1212.     Procedure xmouseinit;
  1213.  
  1214.     Initialize the mouse driver functions and install the mouse event handler
  1215.     function. This is the first function you must call before using any of the
  1216.     mouse functions. This mouse code uses the fastest possible techniques to
  1217.     save and restore mouse backgrounds and to draw the mouse cursor.
  1218.  
  1219.     WARNING: This function uses and updates "NonVisualOffset" to allocate
  1220.          video ram for the saved mouse background.
  1221.  
  1222.     LIMITATIONS: No clipping is supported horizontally for the mouse cursor
  1223.                  No validity checking is performed for NonVisualOffs
  1224.  
  1225.     **WARNING** You must Hide or at least Freeze the mouse cursor while drawing
  1226.                 using any of the other XLIB procedures since the mouse handler may
  1227.                 modify vga register settings at any time. VGA register settings
  1228.                 are not preserved which will result in unpredictable drawing
  1229.                 behavior. If you know the drawing will occur away from the
  1230.                 mouse cursor set MouseFrozen to TRUE (1), do your drawing
  1231.                 then set it to FALSE (0). Alternatively call "xhidemouse",
  1232.                 perform your drawing and then call "xshowmouse". Another
  1233.                 alternative is to disable interrupts while drawing but usually
  1234.                 drawing takes up alot of time and having interrupts disabled
  1235.                 for too long is not a good idea.
  1236.  
  1237.     xdefinemousecursor
  1238.     ------------------
  1239.  
  1240.     Procedure xdefinemousecursor( var MouseDef; MouseColor : byte );
  1241.  
  1242.         MouseDef - a pointer to 14 characters containing a bitmask for all the
  1243.                  cursor's rows.
  1244.         MouseColor - The colour to use when drawing the mouse cursor.
  1245.  
  1246.     Define a mouse cursor shape for use in subsequent cursor redraws. XMouse
  1247.     has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.
  1248.  
  1249.     WARNING: This function assumes MouseDef points to 14 bytes.
  1250.  
  1251.     Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..
  1252.     bit 0 represents pixel 7 in each "MouseDef" byte.
  1253.  
  1254.     xshowmouse
  1255.     ----------
  1256.  
  1257.     Procedure xshowmouse;
  1258.  
  1259.     Makes the cursor visible if it was previously hidden.
  1260.     See Also: "xhidemouse".
  1261.  
  1262.     xhidemouse
  1263.     ----------
  1264.  
  1265.     Procedure xhidemouse;
  1266.  
  1267.     Makes the cursor hidden if it was previously visible.
  1268.     See Also: "xshowmouse".
  1269.  
  1270.     xmouseremove
  1271.     ------------
  1272.  
  1273.     Procedure xmouseremove;
  1274.  
  1275.     Stop mouse event handling and remove the mouse handler.
  1276.  
  1277.     NOTE: This function MUST be called before quitting the program if
  1278.              a mouse handler has been installed
  1279.  
  1280.     xpositionmouse
  1281.     --------------
  1282.  
  1283.     Procedure xpositionmouse( x,y : integer );
  1284.  
  1285.     Positions the mouse cursor at the specified location
  1286.  
  1287.     xmousewindow
  1288.     ------------
  1289.  
  1290.     Procedure xmousewindow( x0, y0, x1, y1 : integer );
  1291.  
  1292.     Defines a mouse window.
  1293.  
  1294.     xupdatemouse
  1295.     ------------
  1296.  
  1297.     Procedure xupdatemouse;
  1298.  
  1299.     Forces the mouse position to be updated and cursor to be redrawn.
  1300.     Note: this function is useful when you have set "MouseFrozen" to true.
  1301.     Allows the cursor position to be updated manually rather than
  1302.     automatically by the installed handler.
  1303.  
  1304. ╔═══════════════════════════════════════════════════════════════════════════╗
  1305. ║ BITMAP TOOLS                                                              ║
  1306. ╚═══════════════════════════════════════════════════════════════════════════╝
  1307.  
  1308.     xpbmtobm
  1309.     --------
  1310.     Procedure xpbmtobm( var sourcepbm, destbm );
  1311.  
  1312.     This function converts a bitmap in the planar format to the linear format
  1313.     as used by xcompilebitmap.
  1314.  
  1315.     WARNING: the source and destination bitmaps must be pre - allocated
  1316.  
  1317.     NOTE: This function can only convert planar bitmaps that are suitable.
  1318.     If the source planar bitmap's width (per plane) is >= 256/4
  1319.     it cannot be converted.
  1320.  
  1321.     xbmtopbm
  1322.     --------
  1323.     Procedure xbmtopbm( var sourcepbm, destbm );
  1324.  
  1325.     This function converts a bitmap in the linear format as used by
  1326.     xcompilebitmap to the planar formap.
  1327.  
  1328.     WARNING: the source and destination bitmaps must be pre - allocated
  1329.  
  1330.     NOTE: This function can only convert linear bitmaps that are suitable.
  1331.     If the source linear bitmap's width is not a multiple of 4
  1332.     it cannot be converted.
  1333.  
  1334.  
  1335. ╔═══════════════════════════════════════════════════════════════════════════╗
  1336. ║ CIRCLE ROUTINES                                                           ║
  1337. ╚═══════════════════════════════════════════════════════════════════════════╝
  1338.  
  1339.         Wheel Have to See About That
  1340.             by Matthew MacKenzie
  1341.  
  1342. The circle procedures are :
  1343.     o  xcircle, oddly enough, draws a circle.
  1344.     o  xfilledcircle does too, only the circle is filled (in some
  1345.          libraries this is called a disc).
  1346.  
  1347.     The word `circle' here refers to a round thing which is as many
  1348. pixels tall as across.  It only looks like a circle in 320x240 mode --
  1349. the original mode X -- and in 376x282 mode.
  1350.         In both procedures, the circle is specified by the coordinates of the
  1351. upper-left-hand corner of the smallest box which holds it, and the
  1352. diameter.  Some circle functions have you specify a center point;
  1353. this system is kind of odd because a circle with an even diameter does
  1354. not have a particular pixel for a center.  Every circle, on the other
  1355. hand, has a box with an upper-left corner.
  1356.         No bounds are checked.  A diameter of zero will draw nothing, and
  1357. a negative diameter will blow your VGA board into hundreds of thousands
  1358. of tiny little smoldering fragments.  Neither function supports clipping.
  1359.         The calculation of the circle is based on an algorithm described
  1360. by Michael P. Lindner in a letter to the editor on page 8 of Dr. Dobb's
  1361. Journal #169 (October 1990).  The algorithm has been rearranged to
  1362. allow drawing and moving the plots in the eight octants to be performed
  1363. in one step, so that each pixel does not have to be loaded into the CPU
  1364. twice.  xfilledcircle does not take advantage of this optimization
  1365. because it handles different parts of each plot at different times.
  1366.  
  1367.     xcircle
  1368.     ------
  1369.     Procedure xcircle ( Left, Top, Diameter, Color, ScreenOffs : word );
  1370.  
  1371.     Draws a circle with the given upper-left-hand corner and diameter,
  1372.     which are given in pixels.
  1373.  
  1374.  
  1375.     xfilledcircle
  1376.     -------------
  1377.     Procedure xfilledcircle( Left, Top, Diameter, Color, ScreenOffs : word );
  1378.  
  1379.     Draws a filled circle with the given upper-left-hand corner and
  1380.     diameter.
  1381.  
  1382. ╔═══════════════════════════════════════════════════════════════════════════╗
  1383. ║ POLYGON ROUTINES                                                          ║
  1384. ╚═══════════════════════════════════════════════════════════════════════════╝
  1385.  
  1386.  
  1387.     xtriangle
  1388.     ---------
  1389.  
  1390.     Procedure xtriangle( x0, y0, x1, y1, x2, y2, color, PageBase : word );
  1391.  
  1392.     This procedure draws a filled triangle which is clipped to the current
  1393.     clipping window defined by TopClip,BottomClip,LeftClip,RightClip.
  1394.     Remember: the X clipping variable are in byteS not PIXELS so you
  1395.         can only clip to 4 pixel byte boundaries.
  1396.  
  1397.  
  1398.     xpolygon
  1399.     --------
  1400.  
  1401.     Procedure xpolygon( var vertices; numvertices, color, PageBase : word );
  1402.  
  1403.     This procedure is similar to the triangle function but draws
  1404.     convex polygons. The vertices are supplied in the form of a FAR
  1405.     pointer.
  1406.  
  1407.     NOTE: a convex polygon is one such that if you draw a line from
  1408.     any two vertices, every point on that line will be within the
  1409.     polygon.
  1410.  
  1411.     This procedure works by splitting up a polygon into its component
  1412.     triangles and calling the triangle routine above to draw each one.
  1413.     Performance is respectable but a custom polygon routine might be
  1414.     faster.
  1415.  
  1416. ╔═══════════════════════════════════════════════════════════════════════════╗
  1417. ║ REFERENCE SECTION                                                         ║
  1418. ╚═══════════════════════════════════════════════════════════════════════════╝
  1419.  
  1420. In my opinion Doctor Dobbs Journal is the best reference text for
  1421. VGA Mode X graphics:
  1422.  
  1423. Issue 178 Jul 1991 : First reference to Mode X
  1424. Article Abstract   : VGA's undocumented Mode X supports page flipping,
  1425.                  makes off screen memory available, has square pixels,
  1426.                  and increases performance by as muck as 4 times.
  1427.  
  1428. Issue 179 Aug 1991 : Continuation
  1429. Article Abstract   : Michael discusses latches and VGA's undoccumented
  1430.                  Mode X.
  1431.  
  1432. Issue 181 Sep 1991 : Continuation
  1433. Article Abstract   : Michael puts the moves on animation using VGA's 256
  1434.                  colors.
  1435.  
  1436. Issue 184 Oct 1991 : First of a continuing series covering 3-D animation
  1437.                  using VGA's Mode X. This series is still ongoing
  1438.                  (October 1992)
  1439. Article Abstract   : Michael moves into 3-D animation, starting with basic
  1440.                  polygon fills and page flips.
  1441.  
  1442.  
  1443. WHAT IS MODE X ?
  1444. ----------------
  1445.  
  1446. Mode X is a derivative of the VGA's standard mode 13h (320x200 256 color).
  1447. It is a (family) of undocumented video modes that are created by tweaking
  1448. the VGA's registers. The beauty of mode X is that it offers several
  1449. benefits to the programmer:
  1450.  - Multiple graphice pages where mode 13h doesn't allowing for page flipping
  1451.      (also known as double buffering) and storage of images and data in
  1452.      offscreen video memory
  1453.  - A planar video ram organization which although more difficult to program,
  1454.      allows the VGA's plane-oriented hardware to be used to process pixels in
  1455.      parallel, improving performance by up to 4 times over mode 13h
  1456.  
  1457.      See issue 178-179 of D.D.J. for a full description of VGA's Mode X.
  1458.  
  1459. WHAT IS A SPLIT SCREEN ?
  1460. ------------------------
  1461.  
  1462. A split screen is a neat hardware feature offered by the EGA and VGA video
  1463. cards. A split screen is a mode of graphics operationin which the Hardware
  1464. splits the visual graphics screen horizontally and treats both halves as
  1465. individual screens each starting at different locations in video RAM.
  1466.  
  1467. The bottom half (which is usually referred to as the split screen) always
  1468. starts at address A000:0000 but the top half's starting address is user
  1469. definable.
  1470.  
  1471. The most common application of split screens in games is the status display
  1472. in scrolling games. Split screens make this sort of game simpler to program
  1473. because when the top half window is scrolled the programmer does not have to
  1474. worry about redrawing the bottom half.
  1475.  
  1476. WHAT IS DOUBLE BUFFERING ?
  1477. --------------------------
  1478.  
  1479. Double buffering (also known as page flipping) is the technique most often
  1480. used to do animation. it requires hardware that is capable of displaying
  1481. multiple graphics pages (or at least 2). Animation is achieved by drawing
  1482. an image in the non visible screen and then displaying the non visible
  1483. screen. Once the page has been flipped the process starts again. The next
  1484. frame of the animation is drawn on the non visible screen, the page is
  1485. flipped again etc.
  1486.  
  1487.  
  1488. WHAT IS TRIPLE BUFFERING ?
  1489. --------------------------
  1490.  
  1491. Triple buffering is similar to double buffering in many ways, but it
  1492. relies on 3 pages being defined for animation. The main selling point
  1493. of triple buffering is that it eliminates the need to wait for the
  1494. vertical retrace to flip pages before drawing on the new page thus
  1495. alowing the programmer to start building the next animation frame
  1496. immediately after completing the current one. Heres how it works:
  1497.  
  1498. With double buffering, once you complete drawing the hidden page and
  1499. youre ready to flip pages, you have to wait for the VGA hardware to
  1500. actually flip the page (during the vertical retrace) before you start
  1501. drawing the next page otherwise you will be drawing on the visible page.
  1502.  
  1503. With triple buffering you cycle between three pages, thus the page you
  1504. draw on is guaranteed not to be visible. I know this is a poor
  1505. description but it really is quite simple
  1506.  
  1507. Triple buffering can acheive the fastest possible animation under the
  1508. right conditions but the draw back is that more video RAM is required. If
  1509. you wish to store bitmaps in video ram such as background tiles, double
  1510. buffering would be the better alternative.
  1511.  
  1512.